layui.define(['jdhp'], function (exports) {
    function design_tr_main(args) {
        if (window.jdiyAdmin === undefined) window.jdiyAdmin = {};
        let body = $('body'),
            $g = s => $('#' + s + '_' + args.uid),
            canvas = $g('trCanvas'),
            rtForm = $g('trProps'),
            divBtn0 = $g('ls_btn0Div'),
            $selBtn = () => {
                let t = canvas.find('.jdiy-selected'),
                    pos = t.hasClass('topbtn') ? 0 : 1;
                return {t: t, pos: pos, d: sBtns[pos][t.attr('id').substring(10)]}
            },
            $selCol = () => {
                let t = canvas.find('.jdiy-selected');
                return {t: t, d: sCols[t.attr('id').substring(10)]}
            },
            $gs = function (s, h = []) {
                if (s.length) for (let i = s.length; i--;) $g(s[i]).show();
                if (h.length) for (let i = h.length; i--;) $g(h[i]).hide();
            },
            fillOpts = (o, pleaseText, items, selVal, jgFunc = (it) => it) => {
                let sa = pleaseText === false ? [] : ['<option value="">' + pleaseText + '</option>'];
                for (let i = 0; i < items.length; i++) {
                    let [v, k] = jgFunc(items[i]);
                    sa.push('<option value="' + v + '"' + (String(v) === String(selVal) ? ' selected' : '') + '>' + k + '</option>');
                }
                return o.html(sa.join(''));
            },
            sData = {},
            sBtns = [{}, {}],
            sCols = {},
            opers = {
                'eq': '等于',
                'ne': '不等于',
                'lt': '小于',
                'gt': '大于',
                "lte": '小于等于',
                "gte": '大于等于',
                "like": "包含"
            },
            btnTypes = [
                [
                    ['add', '添加'],
                    ['page', '打开新界面'],
                    ['link', "打开自定义页面"],
                    ['ajax', '执行自定义Ajax请求']
                ],
                [
                    ['edit', '修改'],
                    ['del', '删除'],
                    ['view', '详情页'],
                    ['add', '添加下级'],
                    ['page', '打开新界面'],
                    ['link', '打开自定义页面'],
                    ['update', '更新字段值'],
                    ['ajax', '执行自定义Ajax请求'],
                    ['exec', '执行代码(列表增强)']
                ]
            ],
            getColText = (c) =>
                c.field === sData.nameField
                    ? c.field || ''
                    : (
                        (c.format === 'manyToOne' && c.field ? c.field + ' <strong style="color:#c00">↓</strong>' : '') +
                        (c.format === 'oneToMany' ? '<div style="color:gray">一对多</div>' : '') +
                        (c.format === 'manyToMany' ? '<div style="color:gray">多对多</div>' : '') +
                        (c.format === 'tpl' ? '<div style="color:gray">模板</div>' : '') +
                        (c.format === 'img' ? '<div style="color:gray"><i class="layui-icon layui-icon-picture"></i></div>' : '') +
                        (c.format === 'file' ? '<div style="color:gray"><i class="layui-icon layui-icon-link"></i></div>' : '') +
                        (',manyToOne,oneToMany,manyToMany,'.indexOf(c.format) === -1
                                ? c.field || ''
                                : (c.joinTable && c.joinField ? '<div style="color:#767d07">' + c.joinTable + "." + c.joinField + '</div>' : '')
                        )
                    )
            ,
            selectOn = function (a, b) {
                layui.form.on('select(' + a + '_' + args.uid + ')', b);
            },
            switchOn = function (a, b) {
                layui.form.on('switch(' + a + '_' + args.uid + ')', b);
            },
            col_fieldsOn = function (o) {
                let {d} = $selCol();
                if (o.value === '@') {
                    $gs(['col_tFieldDiv']);
                    $g('col_tField').val(d.field || '');
                } else {
                    d.field = o.value;
                    $gs([], ['col_tFieldDiv']);
                }
                if (d.field === sData.nameField) $gs([], ['col_alignDiv']);
                else $gs(['col_alignDiv']);
                if (d.field === sData.nameField) {
                    $('#jdiylsoth_' + d.id).css('text-align', 'left').addClass('nameCol');
                    $('#jdiylsotd_' + d.id).css('text-align', 'left').addClass('nameCol')
                        .html('<span class="ew-tree-pack"><i class="ew-tree-table-arrow layui-icon"></i></span>' + d.field);
                } else {
                    $('#jdiylsoth_' + d.id).css('text-align', d.align).remove('nameCol');
                    $('#jdiylsotd_' + d.id).css('text-align', d.align).remove('nameCol')
                        .html(d.field).html(getColText(d));
                }
                layui.form.render('select', rtForm.attr('id'));
            },
            loadFields = function (e, et, s) {
                $.ajax({
                    url: jdiyAdmin.ctx + '/mgmt/JDiyAdmin/ui.' + (e ? 'fields?entity=' : 'columns?table=') + et,
                    success: s
                });
            },
            col_manyTableOn = function (o) {
                let {d} = $selCol();
                d.manyTable = o.value;
                loadFields(false, o.value, function (ret) {
                    fillOpts($g('col_manyField0'), '正向关联本表字段', ret.data, d.manyField0, (it) => [
                        it[0], it[0] + '　- ' + it[1]
                    ]);
                    fillOpts($g('col_manyField1'), '反向关联外表字段', ret.data, d.manyField1, (it) => [
                        it[0], it[0] + '　- ' + it[1]
                    ]);
                    layui.form.render('select', rtForm.attr('id'));
                });
            },
            col_joinTableOn = function (o) {
                let {d} = $selCol();
                d.joinTable = o.value;
                loadFields(false, o.value, function (r) {
                    fillOpts($g('col_joinField'), '请选择外联显示字段', r.data, d.joinField, (it) => [
                        it[0], it[0] + '　- ' + it[1]
                    ]);
                    fillOpts($g('col_joinRef'), '请选择外键字段', r.data, d.joinRef, (it) => [
                        it[0], it[0] + '　- ' + it[1]
                    ]);
                    $('#jdiylsotd_' + d.id).html(getColText(d));
                    layui.form.render('select', rtForm.attr('id'));
                });
            },
            addNewId = 1,
            setOpacity = function (o, v) {
                if (o.hasClass('col')) {
                    let index = o.index() + 1;
                    canvas.find('.jdiy-ls-design-tb thead th:nth-child(' + index + ')').css({opacity: v});
                    canvas.find('.jdiy-ls-design-tb tbody td:nth-child(' + index + ')').css({opacity: v});
                } else {
                    o.css({opacity: v});
                }
                return o;
            },
            getLineCss = (t) => {
                if (t.hasClass('col')) {
                    let index = t.index() + 1,
                        o1 = canvas.find('.jdiy-ls-design-tb thead th:nth-child(' + index + ')'),
                        o2 = canvas.find('.jdiy-ls-design-tb tbody td:nth-child(' + index + ')');
                    return {
                        width: '3px',
                        height: (o1.outerHeight() + o2.outerHeight() + 2) + 'px',
                        top: (o1.offset().top) + 'px'
                    }
                } else {
                    return {width: '3px', height: t.outerHeight() + 'px', top: (t.offset().top) + 'px'}
                }
            },
            startDrag = function (e, dragThis) {
                body.addClass('drag-move');
                jdiyAdmin.lsDesign.dragging = true;
                jdiyAdmin.lsDesign.dragThis = setOpacity(dragThis, 0.1);
                jdiyAdmin.lsDesign.mouse = {x: e.clientX, y: e.clientY};
            },
            footerBtnShow = function (d) {
                if (d.footer === undefined || d.footer === null) d.footer = true;
                if (d.act === 'link' && d.target === 'dialog') {
                    $g('btn_footerDiv').show();
                    $g('btn_footer').prop('checked', d.footer);
                    layui.form.render(null, rtForm.attr('id'));
                }
            },
            save = function () {
                let selectedId = canvas.find('.jdiy-selected').attr('id');
                jdiyAdmin.ajax({
                    url: jdiyAdmin.ctx + '/mgmt/JDiyAdmin/tree.saveDesign.' + args.uid,
                    data: {s: JSON.stringify(sData)},
                    type: 'post',
                    success: function (ret) {
                        if (ret.code !== 200) {
                            if (ret.code === 203 && ret.inputId) doSelect(ret.inputId);
                            jdiyAdmin.error(ret.msg);
                            return;
                        }
                        reset(null, selectedId);
                        layui.layer.msg(ret.msg);
                    }
                });
            },
            addNew = function (t) {
                let id = jdiyAdmin.util.newId(),
                    oid = t.attr('id').substring(10),
                    aa = function (arr, d) {
                        let is = false, i;
                        for (i = arr.length; i--;) {
                            if (arr[i].id === oid) {
                                arr.splice(i + 1, 0, d);
                                is = true;
                                break;
                            }
                        }
                        if (!is) arr.push(d);
                    },
                    createBtn = function (pos) {
                        let d = sBtns[pos][id] = {
                            id: id,
                            text: '新按钮' + addNewId++,
                            act: pos === 0 ? 'add' : 'edit'
                        }, arr = pos === 0 ? sData.topButtons : sData.rowButtons;
                        aa(arr, d);
                        doSelect($(builder.btn(d, pos)).insertAfter(t));
                        layui.layer.msg('[' + sBtns[pos][id].text + '] 已添加并选中，请在页面右侧配置其属性。');
                    };
                if (!t.length) return;
                if (t.hasClass('rowbtn')) {
                    createBtn(1);
                } else if (t.hasClass('topbtn')) {
                    createBtn(0);
                } else if (t.hasClass('col')) {
                    let nd = {
                        id: id,
                        label: '新列' + addNewId++,
                        format: 'text',
                        align: 'center',
                        sortable: false
                    };
                    aa(sData.columns, nd);
                    builder.cols(sData.columns);
                    doSelect('jdiylsoth_' + id);
                }
            },

            remove = function (t) {
                let id = t.attr('id').substring(10), n, l, i, p = 'jdiylsobj_',
                    update = (a) => {
                        for (i = a.length; i--;) {
                            if (a[i].id === id) {
                                if (i < a.length - 1) n = a[i + 1];
                                else if (i > 0) n = a[i - 1];
                                else n = null;
                                a.splice(i, 1);
                                break;
                            }
                        }
                        return a;
                    };
                if (t.hasClass('col')) {
                    if (sData.columns.length < 2) {
                        layui.layer.msg('至少需要保留一列数据,再删就没有了！');
                        return;
                    }
                    builder.cols(update(sData.columns));
                    p = 'jdiylsoth_';
                } else if (t.hasClass('topbtn')) {
                    l = sBtns[0][id].text;
                    if (update(sData.topButtons).length < 1) builder.emptyTopBtn();
                    else t.remove();
                } else if (t.hasClass('rowbtn')) {
                    l = sBtns[1][id].text;
                    if (update(sData.rowButtons).length < 1) builder.cols(sData.columns);
                    else t.remove();
                }
                if (n) doSelect(p + n.id);
                else propRender.nul();
                layui.layer.msg((l ? '[' + l + ']' : '目标对象') + '已从当前区域移除！');
            },
            toolHtml = '<div class="layui-btn-group jdiy-design-tool">\n' +
                '        <button type="button" class="layui-btn layui-btn-xs layui-bg-black add-tool" title="在它后面增加"><i class="layui-icon layui-icon-add-1"></i></button>\n' +
                '<button type="button" class="layui-btn layui-btn-xs layui-bg-black del-tool" title="移除选中项"><i class="layui-icon layui-icon-delete"></i></button>\n' +
                '    </div>',
            showTool = function (t, isCol) {
                canvas.find('.jdiy-design-tool').remove();
                if (t) {
                    let tool = isCol
                        ? $(toolHtml).prependTo(t).css({
                            marginLeft: 0,
                            marginTop: (t.height()) + 'px'
                        })
                        : $(toolHtml).insertAfter(t).css({
                            marginLeft: Math.max(-65, -t.innerWidth()) + 'px',
                            marginTop: (t.outerHeight()) + 'px'
                        });
                    tool.find('.add-tool').click(function () {
                        let t = canvas.find('.jdiy-selected');
                        if (t.length > 1) t = t.filter('th');
                        addNew(t);
                    });
                    tool.find('.del-tool').click(function () {
                        let t = canvas.find('.jdiy-selected');
                        if (t.length > 1) t = t.filter('th');
                        showTool();
                        remove(t);
                    });
                }
            },
            doSelect = function (target) {
                let oThis = typeof target == 'string' ? $('#' + target) : target, o = oThis;
                if (oThis.is('.jdiy-ls-obj.col')) {
                    layui.element.tabChange('rtTab_' + args.uid, 'rtTab0_' + args.uid);
                    var index = o.index() + 1, otd;
                    canvas.find('.jdiy-ls-obj.jdiy-selected').removeClass('jdiy-selected');
                    canvas.find('.jdiy-ls-design-tb thead th:nth-child(' + index + ')').addClass('jdiy-selected');
                    otd = canvas.find('.jdiy-ls-design-tb tbody td:nth-child(' + index + ')').addClass('jdiy-selected');
                    $('.ls-tpl_' + args.uid).hide();
                    $gs(['ls_cols'], ['nulPropDiv']);
                    propRender.cols(sCols[o.attr('id').substring(10)], o);
                    showTool(otd, true);
                } else if ((o = oThis).is('.jdiy-ls-obj.rowbtn') || (o = oThis.parents('.jdiy-ls-obj.rowbtn')).length === 1) {
                    layui.element.tabChange('rtTab_' + args.uid, 'rtTab0_' + args.uid);
                    canvas.find('.jdiy-ls-obj.jdiy-selected').removeClass('jdiy-selected');
                    o.addClass('jdiy-selected');
                    $('.ls-tpl_' + args.uid).hide();
                    $gs(['ls_btns'], ['nulPropDiv']);
                    propRender.btns(sBtns[1][o.attr('id').substring(10)], 1);
                    showTool(o);
                } else if ((o = oThis).is('.jdiy-ls-obj.topbtn') || (o = oThis.parents('.jdiy-ls-obj.topbtn')).length === 1) {
                    layui.element.tabChange('rtTab_' + args.uid, 'rtTab0_' + args.uid);
                    canvas.find('.jdiy-ls-obj.jdiy-selected').removeClass('jdiy-selected');
                    o.addClass('jdiy-selected');
                    $('.ls-tpl_' + args.uid).hide();
                    $gs(['ls_btns'], ['nulPropDiv']);
                    propRender.btns(sBtns[0][o.attr('id').substring(10)], 0);
                    showTool(o);
                } else if ((o = oThis).is('.jdiy-ls-obj.pager') || (o = oThis.parents('.jdiy-ls-obj.pager')).length === 1) {
                    layui.element.tabChange('rtTab_' + args.uid, 'rtTab1_' + args.uid);
                    canvas.find('.jdiy-ls-obj.jdiy-selected').removeClass('jdiy-selected');
                    o.addClass('jdiy-selected');
                    $gs([], ['nulPropDiv']);
                }
            },
            propRender = {
                nul: function () {
                    rtForm.find('.ls-tpl_' + args.uid).hide();
                    rtForm.find('#nulPropDiv_' + args.uid).show();
                    layui.element.tabChange('rtTab_' + args.uid, 'rtTab1_' + args.uid);
                },
                cols: function (col, t) {
                    let o = $g('col_field'), val = col.field;
                    loadFields(args.bindType === 'entity', args.bindType === 'table' ? args.mainTable : args.mainEntity, function (r) {
                        let jg = (it) => [it[0], it[0] + '　- ' + it[1]];
                        fillOpts($g('col_field'), '请选择', r.data, val, jg);
                        $g('col_field').append('<option value="@">其它自定义</option>');
                        if (val && !o.find('option[value="' + val + '"]').length) {
                            o.val('@');
                        }
                        col_fieldsOn({value: o.val()});

                        fillOpts($g('nameField'), '请选择树形显示列', r.data, sData.nameField || 'name', jg);
                        fillOpts($g('pidField'), '请选择', r.data, sData.pidField || (args.bindType === 'entity' ? 'parent.id' : 'parentId'), jg);
                        fillOpts($g('sortField'), '不指定(默认 id主键)', r.data, sData.sortField || 'sortIndex', jg);
                        fillOpts($g('pathField'), '请选择', r.data, sData.pathField || 'sortPath', jg);

                        $g('col_label').val(col.label || '');
                        o = $g('col_format');
                        try {
                            o.val(col.format || '');
                        } catch (e) {
                            o.val('');
                        }

                        $g('col_width').val(col.width || '');

                        rtForm.find('.coldivs').hide();

                        if (!t.hasClass('nameCol')) {
                            $gs(['col_alignDiv']);
                        }

                        o = $g('col_align');
                        try {
                            o.val(col.align || 'center');
                        } catch (e) {
                            o.val('center');
                        }


                        if (col.format === 'kv') {
                            $gs(['col_kvDiv']);
                            $g('col_kv').val(col.kv || '');
                        } else if (col.format === 'tpl') {
                            $gs(['col_tplDiv']);
                            $g('col_tpl').val(col.tpl || '')
                                .attr('placeholder', '支持ftl语法，例：\r\n\r\n<#if vo.state=1>\r\n ${vo.auser} 审核于：\r\n ${vo.atime?datetime}\r\n<#else>\r\n 未审核\r\n</#if>');
                        } else if (col.format === 'dict') {
                            $gs(['col_dictIdDiv']);
                            $g('col_dictId').val(col.dictId || '');
                        } else if (col.format === 'manyToOne' || col.format === 'manyToMany' || col.format === 'oneToMany') {
                            $gs(['col_outJoinDiv']);
                            o = $g('col_joinTable');
                            try {
                                o.val(col.joinTable || '');
                            } catch (e) {
                                o.val('');
                            }
                            col_joinTableOn({value: o.val()});
                            if (col.format === 'manyToOne') {
                                $gs([], ['col_manyTableDiv', 'col_manyField0Div', 'col_manyField1Div', 'col_joinRefDiv']);
                            } else if (col.format === 'manyToMany') {
                                $gs(['col_manyTableDiv', 'col_manyField0Div', 'col_manyField1Div'], ['col_joinRefDiv']);
                                $g('col_manyTable').val(col.manyTable || '');
                                col_manyTableOn({value: col.manyTable || ''});
                            } else if (col.format === 'oneToMany') {
                                $gs(['col_joinRefDiv'], ['col_manyTableDiv', 'col_manyField0Div', 'col_manyField1Div']);
                            }
                        } else if (col.format === 'tree') {
                            $gs(['col_treesDiv']);
                            o = $g('col_treeId');
                            try {
                                o.val(col.treeId || '');
                            } catch (e) {
                                o.val('');
                            }
                            o = $g('col_treeDisplay');
                            try {
                                o.val(col.treeDisplay || 'separator');
                            } catch (e) {
                                o.val('');
                            }
                        }
                        layui.form.render(null, rtForm.attr('id'));
                    });
                },
                colOther: function () {
                    $g('ls_rowNum').prop('checked', !!sData.rowNum);
                    $g('lazy').prop('checked', !!sData.lazy);

                    if (sData.mge === undefined || sData.mge) {
                        $g('ls_mge').prop('checked', true);
                        $gs(['ls_mgeWidthDiv']);
                    } else {
                        $g('ls_mge').prop('checked', false);
                        $gs([], ['ls_mgeWidthDiv']);
                    }
                    $g('ls_mgeWidth').val(sData.mgeWidth === undefined ? '' : sData.mgeWidth);
                    $g('sqlFilter').val(sData.sqlFilter || '');
                    $g('rootPid').val(sData.rootPid || (sData.rootPid = 'nullValue'));

                    loadFields(args.bindType === 'entity', args.bindType === 'table' ? args.mainTable : args.mainEntity, function (r) {
                        let jg = (it) => [it[0], it[0] + '　- ' + it[1]];
                        sData.nameField = fillOpts($g('nameField'), '请选择树形显示列', r.data, sData.nameField || 'name', jg).val();
                        sData.pidField = fillOpts($g('pidField'), '请选择', r.data, sData.pidField || (args.bindType === 'entity' ? 'parent.id' : 'parentId'), jg).val();
                        sData.sortField = fillOpts($g('sortField'), '不指定(默认 id主键)', r.data, sData.sortField || 'sortIndex', jg).val();
                        sData.pathField = fillOpts($g('pathField'), '请选择', r.data, sData.pathField || 'sortPath', jg).val();

                        layui.form.render(null, rtForm.attr('id'));
                    });

                    $g('pageHandler').val(sData.pageHandler || '');

                    $g('headTips').val(sData.headTips || '');
                    if (sData.headTips != null && sData.headTips !== '') {
                        $g('headTipsBlock').html(sData.headTips).show();
                    }
                    $g('footTips').val(sData.footTips || '');
                    if (sData.footTips != null && sData.footTips !== '') {
                        $g('footTipsBlock').html(sData.footTips).show();
                    }

                    layui.form.render(null, rtForm.attr('id'));
                },
                btns: function (btn, pos) {
                    $g('btn_text').val(btn.text || '');
                    $g('btn_icon').val(btn.icon || (btn.icon = ''));
                    let sa = [], ae = btn.act === 'add' || btn.act === 'edit',
                        types = btnTypes[pos], act = btn.act, i;
                    fillOpts($g('btn_act'), false, types, btn.act);
                    btn.act = $g('btn_act').val();

                    $(rtForm).find('.btnpls').hide();/*先把不同类型的都隐藏*/
                    if (act === 'add' || act === 'edit' || act === 'view' || act === 'page') {
                        $gs(['btn_pageIdDiv', 'btn_targetDiv', 'btn_titleDiv']);
                        let wrapOne = (it) => '<option value="' + it.id + '"' + (it.id === btn.goPageId ? ' selected' : '') + '>' + it.name + '</option>';
                        if (ae) {
                            sa = [];
                            for (i = 0; i < args.pageList.length; i++) {
                                if (args.pageList[i].type !== 'form' || !args.pageList[i].isMainTable) continue;
                                sa.push(wrapOne(args.pageList[i]));
                            }
                        } else if (act === 'view') {
                            sa = [];
                            for (i = 0; i < args.pageList.length; i++) {
                                if (args.pageList[i].type !== 'view' || !args.pageList[i].isMainTable) continue;
                                sa.push(wrapOne(args.pageList[i]));
                            }
                        } else {
                            sa = ['<option value="">=请选择=</option>'];
                            let inArr = [], lsArr = [], trArr = [], viArr = [];
                            for (i = 0; i < args.pageList.length; i++) {
                                let opt = wrapOne(args.pageList[i]), tpl = args.pageList[i].type;
                                if (tpl === 'form') inArr.push(opt);
                                else if (tpl === 'list') lsArr.push(opt);
                                else if (tpl === 'tree') trArr.push(opt);
                                else if (tpl === 'view') viArr.push(opt);
                            }
                            if (viArr.length) sa.push('<optgroup label="详情界面">', viArr.join('\n'), '</optgroup>');
                            if (inArr.length) sa.push('<optgroup label="表单界面">', inArr.join('\n'), '</optgroup>');
                            if (lsArr.length) sa.push('<optgroup label="列表界面">', lsArr.join('\n'), '</optgroup>');
                            if (trArr.length) sa.push('<optgroup label="树形界面">', trArr.join('\n'), '</optgroup>');
                        }
                        btn.goPageId = $g('btn_pageId').html(sa.join('')).val();

                        if (act === 'page'||act==='add'||act==='edit') {
                            $gs(['btn_pageParamDiv']);
                            $g('btn_pageParam').val(btn.pageParam || '').attr('placeholder', pos === 0 ? '格式：foo=bar&prm2=val' : '例：userId=${vo.id}');
                        }

                        btn.target = fillOpts($g('btn_target'), false, [['dialog', '弹出对话框'], ['tab', '新Tab标签']], btn.target).val();
                        $g('btn_title').val(btn.title || '').attr('placeholder', pos === 0 ? '' : '例：${vo.name}资料修改');
                    } else if (act === 'link') {
                        $gs(['btn_outLinkDiv', 'btn_targetDiv']);
                        $g('btn_outLink').val(btn.outLink || '');
                        btn.target = fillOpts($g('btn_target'), false, [['dialog', '弹出对话框'], ['tab', '新Tab标签'], ['_blank', '浏览器新页面']], btn.target).val();

                        if (btn.target !== '_blank') {
                            $gs(['btn_titleDiv']);
                            $g('btn_title').val(btn.title || '').attr('placeholder', pos === 0 ? '' : '例：${vo.name}资料修改');
                        }
                    }
                    if (btn.act === 'update') {
                        $gs(['btn_updateCodeDiv']);
                        $g('btn_updateCode').val(btn.updateCode || '');
                    }
                    if (btn.act === 'del' || btn.act === 'update' || btn.act === 'exec' || btn.act === 'ajax') {
                        $gs(['btn_confirmDiv']);
                        $g('btn_confirm').val(btn.confirm || '');
                        if (btn.act === 'ajax') {
                            $gs(['btn_ajaxUrlDiv']);
                            $g('btn_ajaxUrl').val(btn.ajaxUrl || '');
                        }
                    }
                    if (btn.target === 'dialog'
                        && (btn.act === 'add' || btn.act === 'edit' || btn.act === 'view' || btn.act === 'page' || btn.act === 'link')) {
                        $gs(['btn_widthDiv', 'btn_heightDiv']);
                        $g('btn_width').val(btn.width || (btn.width = 640));
                        $g('btn_height').val(btn.height || (btn.height = 480));
                    }
                    if (pos === 1) {
                        $gs(['btn_dblDiv']);
                        $g('btn_dbl').prop('checked', !!btn.dbl);
                    }
                    $gs(['btn_grantCodeDiv', 'btn_conditionShowDiv']);
                    $g('btn_grantCode').val(btn.grantCode || '');
                    $g('btn_conditionShow').val(btn.conditionShow || '');
                    layui.colorpicker.render({
                        elem: '#btn_fg_' + args.uid
                        , color: btn.fg || ''
                        , predefine: true
                        , done: function (color) {
                            btn.fg = color;
                            var t = canvas.find('.jdiy-selected');
                            t.find('button').css({color: color});
                        }
                    });
                    layui.colorpicker.render({
                        elem: '#btn_bg_' + args.uid
                        , color: btn.bg || ''
                        , predefine: true
                        , done: function (color) {
                            btn.bg = color;
                            let t = canvas.find('.jdiy-selected');
                            t.find('button').css({backgroundColor: color});
                        }
                    });

                    footerBtnShow(btn);
                    if (pos == 1) {
                        $gs(['btn_depthShowDiv']);
                        $('input[lay-filter=btn_depthShow_' + args.uid + ']').each(function () {
                            this.checked = (btn.depthShow || 'a').indexOf(this.value) !== -1;
                        });
                    } else {
                        $gs([], ['btn_depthShowDiv']);
                    }
                    layui.form.render(null, rtForm.attr('id'));
                }
            },
            reset = function (data, selectedId) {
                propRender.nul();
                let _done = function () {
                    builder.btns(sData.topButtons, 0, 0);
                    builder.cols(sData.columns);
                    layui.form.render(null, canvas.attr('id'));
                    propRender.colOther();
                    if (selectedId) doSelect(selectedId);
                };
                if (data) {
                    _done();
                } else {
                    jdiyAdmin.ajax({
                        url: jdiyAdmin.ctx + '/mgmt/JDiyAdmin/ui.meta?pageId=' + args.uid,
                        type: 'post',
                        success: function (ret) {
                            if (ret.code !== 200) {
                                jdiyAdmin.error(ret.msg);
                                return;
                            }
                            sData = ret.data;
                            _done();
                        }
                    });
                }

            },
            builder = {
                emptyTopBtn: function () {
                    divBtn0.html('<div class="jdiy-ls-emptyBtn0">无表头控制按钮,在实际应用此行不会显示.　若需增加表头控制按钮，请<button class="layui-btn layui-btn-xs layui-btn-danger">点此添加</button> </div>');
                },
                btns: function (btns, type, pos) {
                    if (!btns || btns.length < 1) {
                        if (type === 0) {
                            builder.emptyTopBtn();
                        } else {
                            $g('ls_btn1Div').html('<div class="jdiy-ls-emptyBtn1">无,若需增加请<button class="layui-btn layui-btn-xs layui-btn-danger">点此添加</button> </div>');
                        }
                        return;
                    }
                    let sa = [], i;
                    for (i = 0; i < btns.length; i++) sa.push(builder.btn(sBtns[type][btns[i].id] = btns[i], pos));
                    $g('ls_btn' + type + 'Div').html(sa.join('\n'));
                },
                btn: (btn, pos) => {
                    let c1 = ['sm', 'xs'],
                        c2 = ['topbtn', 'rowbtn'],
                        text = btn.text || '',
                        icon = btn.icon
                            ? '<i class="layui-icon ' + btn.icon + '"></i>'
                            : '';
                    return '<div class="layui-inline jdiy-ls-obj ' + c2[pos] + '" id="jdiylsobj_' + btn.id
                        + '"><button style="' +
                        (btn.bg && btn.bg !== '' ? 'background-color:' + btn.bg + ';' : '') +
                        (btn.fg && btn.fg !== '' ? 'color:' + btn.fg + ';' : '') +
                        '" class="layui-btn layui-btn-' + c1[pos] + '" type="button">' + icon + text + '</button></div>'
                },
                cols: function (arr) {
                    let sa = [], i;
                    sa.push('<thead><tr>');
                    sa.push('<th class="lsRowNum_' + args.uid + '" style="cursor:not-allowed;width:32px;' + (sData.rowNum ? '' : 'display:none;') + '">行号</th>');
                    for (i = 0; i < arr.length; i++) {
                        sCols[arr[i].id] = arr[i];
                        let nc = arr[i].field === sData.nameField;
                        sa.push('<th class="jdiy-ls-obj col' + (nc ? ' nameCol' : '') + '" id="jdiylsoth_' + arr[i].id + '" style="width:' +
                            (arr[i].width || '') + 'px;text-align:' + (nc ? 'left' : (arr[i].align ? arr[i].align : 'center')) + '">' + arr[i].label + '</th>');
                    }
                    sa.push('<th class="lsMge_' + args.uid + '"' + (sData.mgeWidth ? ' width="' + sData.mgeWidth + '"' : '') + ' style="cursor:not-allowed;' + (sData.mge ? '' : 'display:none;') + '">管理</th>');
                    sa.push('</tr></thead><tbody><tr>');

                    sa.push('<td class="lsRowNum_' + args.uid + '" style="cursor:not-allowed;' + (sData.rowNum ? '' : 'display:none;') + '">1</td>');
                    for (i = 0; i < arr.length; i++) {
                        let nc = arr[i].field === sData.nameField;
                        sa.push('<td class="jdiy-ls-obj col' + (nc ? ' nameCol' : '') + '" id="jdiylsotd_' + arr[i].id +
                            '" style="text-align:' + (nc ? 'left' : (arr[i].align ? arr[i].align : 'center')) + '"><div>' +
                            (nc ? '<span class="ew-tree-pack"><i class="ew-tree-table-arrow layui-icon"></i></span>' : '')
                            + getColText(arr[i]) + '</div></td>');
                    }
                    sa.push('<td class="lsMge_' + args.uid + '" style="' + (sData.mge ? '' : 'display:none;') + '" id="ls_btn1Div_' + args.uid + '"></td></tr></tbody>');
                    $g('jdiy-ls-design-tb').html(sa.join(''));
                    builder.btns(sData.rowButtons, 1, 1);
                }
            };

        if (!body.data('jdiylsdrag')) {
            jdiyAdmin.lsDesign = {
                dragging: false,
                dragThis: null,
                dragThat: null,
                dragTo: null,
                mouse: null,
                pos: 0, /*1左2右*/
                line: $('<div class="jdiy-drag-line"></div>').appendTo(body),
                follow: $('<div class="jdiy-drag-follow">拖拽鼠标可调整当前元素位置</div>').appendTo(body)
            };
            body.data('jdiylsdrag', true);
            body.mousemove(function (evt) {
                let drag = jdiyAdmin.lsDesign;
                if (drag.dragging) {
                    drag.follow.css({
                        left: (evt.clientX + 30) + 'px',
                        top: (evt.clientY + 20) + 'px'
                    }).show();
                }
            }).mouseup(function () {
                $('body').removeClass('drag-move');
                $('.jdiy-drag-highlight').removeClass('jdiy-drag-highlight');
                let drag = jdiyAdmin.lsDesign || {};

                drag.follow.hide();
                drag.line.hide();
                drag.dragTo = null;
                drag.dragging = false;
            });
        }

        canvas.mousedown(function (e) {
            let dragThis = $(e.target),
                selected = canvas.find('.jdiy-selected'),
                isTool = dragThis.hasClass('jdiy-design-tool') || dragThis.parents('.jdiy-design-tool').length > 0;
            if (isTool) return;

            if (!dragThis.hasClass('jdiy-ls-obj')) dragThis = dragThis.parents('.jdiy-ls-obj');
            if (dragThis.is(selected)) {
                let isPager = dragThis.hasClass('pager') || dragThis.parents('.pager').length > 0;
                if (!isPager) {
                    startDrag(e, dragThis);
                    body.addClass('drag-move');
                }
                showTool(false);
            } else if (dragThis.length) {
                doSelect(dragThis);
            }
        }).mousemove(function (e) {
            let drag = jdiyAdmin.lsDesign || {};
            if (!drag.dragging) return;
            let t = $(e.target), c1 = null;
            if (!t.hasClass('jdiy-ls-obj')) t = t.parents('.jdiy-ls-obj');
            if (t.length < 1) return;
            if (drag.dragThis.hasClass('shobj')) c1 = 'shobj';
            else if (drag.dragThis.hasClass('topbtn')) c1 = 'topbtn';
            else if (drag.dragThis.hasClass('rowbtn')) c1 = 'rowbtn';
            else if (drag.dragThis.hasClass('col')) c1 = 'col';
            if (c1 === null || !t.hasClass(c1)) return;
            let that = drag.dragThat = t;

            if (drag.dragThat.is(drag.dragThis)) {
                drag.line.hide();
                drag.dragTo = null;
                drag.follow.html('拖拽鼠标可调整选中元素位置').css('color', 'red').show();
                canvas.find('.jdiy-drag-highlight').removeClass('jdiy-drag-highlight');
            } else {
                let ofX = e.clientX - drag.mouse.x,
                    lazy = 5,//移过指定像素，才判断显示目标位置
                    toob = that,
                    css1 = getLineCss(that);
                if (ofX > lazy) {//右
                    drag.pos = 2;
                    css1.left = (toob.offset().left + toob.outerWidth()) + 'px';
                } else if (ofX < -lazy) {//左
                    drag.pos = 1;
                    css1.left = (toob.offset().left) + 'px';
                } else {
                    css1 = null;
                }
                setOpacity(drag.dragThis, 0.1);
                if (css1 != null) {
                    canvas.find('.jdiy-drag-highlight').removeClass('jdiy-drag-highlight');
                    if (c1 !== 'col') toob.addClass('jdiy-drag-highlight');
                    drag.mouse = {x: e.clientX, y: e.clientY};
                    drag.dragTo = that;
                    drag.line.show().css(css1);
                    drag.follow.show().html('放开鼠标可将元素移至红线处').css('color', 'green');
                }
            }
        }).mouseup(function (e) {
            setTimeout(function () {
                let oThis = canvas.find('.jdiy-selected');
                if (oThis.hasClass('pager')) showTool();
                else if (oThis.length === 1) showTool(oThis);
                else if (oThis.length === 2) showTool(oThis.filter('td'), true)
            }, 200);

            let drag = jdiyAdmin.lsDesign || {};
            if (drag.dragThis) setOpacity(drag.dragThis, 1);
            if (drag.dragging && drag.dragTo) {
                let i, pos, it,
                    fid = drag.dragThis.attr('id').substring(10),
                    tid = drag.dragTo.attr('id').substring(10),
                    mva = function (a, d) {
                        for (i = a.length; i--;) {
                            pos = drag.pos === 1 ? i : i + 1;
                            if ((it = a[i]).id === fid) a.splice(i, 1);
                            else if (it.id === tid) a.splice(pos, 0, d[fid]);
                        }
                        return a;
                    },
                    mv = function () {
                        if (drag.pos === 1) drag.dragThis.insertBefore(drag.dragTo);
                        else drag.dragThis.insertAfter(drag.dragTo);
                    };

                if (drag.pos && drag.line.is(':visible') && fid !== tid) {
                    if (drag.dragThis.hasClass('col')) {
                        builder.cols(mva(sData.columns, sCols));
                        doSelect('jdiylsoth_' + fid);
                    } else if (drag.dragThis.hasClass('topbtn')) {
                        mva(sData.topButtons, sBtns[0]);
                        mv();
                    } else if (drag.dragThis.hasClass('rowbtn')) {
                        mva(sData.rowButtons, sBtns[1]);
                        mv();
                    }
                }
            } else {
                let o = $(e.target), id, label, ok = false;
                if (o.is('.jdiy-ls-emptyBtn0 button')) {
                    ok = true;
                    id = jdiyAdmin.util.newId();
                    label = '添加';
                    sData.topButtons = [{
                        id: id,
                        text: label,
                        icon: 'layui-icon-add-1',
                        act: 'add'
                    }];
                    builder.btns(sData.topButtons, 0, 0);
                } else if (o.is('.jdiy-ls-emptyBtn1 button')) {
                    ok = true;
                    id = jdiyAdmin.util.newId();
                    label = '新按钮' + addNewId++;
                    sData.rowButtons = [{
                        id: id,
                        text: label
                    }];
                    builder.btns(sData.rowButtons, 1, 1);
                }
                if (ok) {
                    doSelect('jdiylsobj_' + id);
                    layui.layer.msg('[' + label + '] 已添加并选中，请在页面右侧配置其属性。');
                }
            }
        });


        $g('btn_text').keyup(function () {
            let {t, pos, d} = $selBtn();
            d.text = this.value;
            $(builder.btn(d, pos)).insertBefore(t).addClass('jdiy-selected');
            t.remove();
        });

        $g('btn_icon').click(function () {
            layui.layer.open({
                type: 8,
                title: '选择图标',
                area: ['480px', '340px'],
                content: jdiyAdmin.ctx + '/mgmt/JDiyAdmin/ui.icon?fn=lsChooseIcon_' + args.uid,
                btn: ['确定', '取消'],
                yes: function (index, layero) {
                    var submit = layero.find("button.submit");
                    submit.click();
                }
            });
            $(this).data('btnid', canvas.find('.jdiy-selected').attr('id'));
        }).change(function () {
            let id = $(this).data('btnid'),
                btnid = id.substring(10),
                t = $('#' + id),
                pos = t.hasClass('topbtn') ? 0 : 1,
                data = sBtns[pos][btnid];
            data.icon = this.value;
            $(builder.btn(data, pos)).insertBefore(t).addClass('jdiy-selected');
            t.remove();
        });
        selectOn('btn_act', function (o) {
            let {pos, d} = $selBtn();
            d.act = o.value;
            propRender.btns(d, pos);
        });

        $g('btn_updateCode').keyup(function () {
            let {d} = $selBtn();
            d.updateCode = this.value;
        });
        selectOn('btn_pageId', function (o) {
            let {d} = $selBtn();
            d.goPageId = o.value;
        });
        $g('btn_pageParam').keyup(function () {
            let {d} = $selBtn();
            d.pageParam = this.value;
        });
        $g('btn_outLink').keyup(function () {
            let {d} = $selBtn();
            d.outLink = this.value;
        });
        selectOn('btn_target', function (o) {
            let {pos, d} = $selBtn();
            d.target = o.value;
            propRender.btns(d, pos);
        });

        $g('btn_title').keyup(function () {
            let {d} = $selBtn();
            d.title = this.value;
        });

        $g('btn_width').keyup(function () {
            let {d} = $selBtn();
            d.width = this.value;
        });

        $g('btn_height').keyup(function () {
            let {d} = $selBtn();
            d.height = this.value;
        });

        $g('btn_confirm').keyup(function () {
            let {d} = $selBtn();
            d.confirm = this.value;
        });
        $g('btn_ajaxUrl').keyup(function () {
            let {d} = $selBtn();
            d.ajaxUrl = this.value;
        });
        $g('btn_grantCode').keyup(function () {
            let {d} = $selBtn();
            d.grantCode = this.value;
        });
        $g('btn_conditionShow').keyup(function () {
            let {d} = $selBtn();
            d.conditionShow = this.value;
        });
        switchOn('btn_dbl', function (o) {
            let {d} = $selBtn();
            for (let i = sData.rowButtons.length; i--;) sData.rowButtons[i].dbl = false;
            d.dbl = o.elem.checked;
        });
        switchOn('btn_footer', function (o) {
            let {d} = $selBtn();
            d.footer = o.elem.checked;
        });
        layui.form.on('checkbox(btn_depthShow_' + args.uid + ')', function () {
            let sa = [];
            $('input[lay-filter=btn_depthShow_' + args.uid + ']:checked').each(function () {
                if (this.checked) sa.push(this.value);
            });
            let {d} = $selBtn();
            d.depthShow = sa.length ? sa.join(',') : 'a';
        });

        selectOn('col_field', col_fieldsOn);
        $g('col_label').keyup(function () {
            let {d} = $selCol();
            $('#jdiylsoth_' + d.id).text(d.label = this.value);
        });

        selectOn('col_format', function (o) {
            let {t, d} = $selCol();
            d.format = o.value;
            propRender.cols(d, t);
        });

        $g('col_kv').keyup(function () {
            let {d} = $selCol();
            d.kv = this.value;
        });
        $g('col_tpl').keyup(function () {
            let {d} = $selCol();
            d.tpl = this.value;
        });

        selectOn('col_dictId', function (o) {
            let {d} = $selCol();
            d.dictId = o.value;
        });


        selectOn('col_joinTable', col_joinTableOn);
        selectOn('col_joinField', function (o) {
            let {d} = $selCol();
            d.joinField = o.value;
            $('#jdiylsotd_' + d.id).html(getColText(d));
        });
        selectOn('col_joinRef', function (o) {
            let {d} = $selCol();
            d.joinRef = o.value;
        });
        selectOn('col_manyTable', col_manyTableOn);
        selectOn('col_manyField0', function (o) {
            let {d} = $selCol();
            d.manyField0 = o.value;
        });
        selectOn('col_manyField1', function (o) {
            let {d} = $selCol();
            d.manyField1 = o.value;
        });
        selectOn('col_treeId', function (o) {
            let {d} = $selCol();
            d.treeId = o.value;
        });
        selectOn('col_treeDisplay', function (o) {
            let {d} = $selCol();
            d.treeDisplay = o.value;
        });

        selectOn('col_align', function (o) {
            let {d} = $selCol();
            d.align = o.value;
            $('#jdiylsoth_' + d.id).css({textAlign: d.align});
            $('#jdiylsotd_' + d.id).css({textAlign: d.align});
        });
        $g('col_tField').keyup(function () {
            let {d} = $selCol();
            if (this.value !== '' && !/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(this.value)) {
                this.value = $(this).data('oldval') || '';
            } else {
                $(this).data('oldval', this.value);
            }
            d.field = this.value;
            $('#jdiylsotd_' + d.id).html(getColText(d));
        });
        $g('col_width').keyup(function () {
            let {d} = $selCol(),
                id = d.id,
                ow = d.width;
            if (this.value !== '') {
                d.width = this.value = parseInt(this.value) || ow || '';
            } else {
                d.width = 0;
            }
            $('#jdiylsoth_' + id).css('width', d.width || '');
        });

        switchOn('ls_rowNum', function (o) {
            if (sData.rowNum = o.elem.checked) {
                canvas.find('.lsRowNum_' + args.uid).show();
            } else {
                canvas.find('.lsRowNum_' + args.uid).hide();
            }
        });
        switchOn('lazy', function (o) {
            sData.lazy = o.elem.checked;
        });
        switchOn('ls_mge', function (o) {
            if (sData.mge = o.elem.checked) {
                canvas.find('.lsMge_' + args.uid).show();
                $gs(['ls_mgeWidthDiv']);
            } else {
                canvas.find('.lsMge_' + args.uid).hide();
                $gs([], ['ls_mgeWidthDiv']);
            }
        });
        $g('ls_mgeWidth').keyup(function () {
            let ov = sData.mgeWidth, v = this.value;
            if (v !== '') {
                if (v != parseInt(v)) v = ov;
                if (v < 0) v = 0;
            }
            sData.mgeWidth = this.value = v;
            builder.cols(sData.columns);
        });
        $g('sqlFilter').blur(function () {
            sData.sqlFilter = this.value;
        });
        selectOn('pageHandler', function (o) {
            sData.pageHandler = o.value;
        });
        selectOn('nameField', function (o) {
            sData.nameField = o.value;
            builder.cols(sData.columns);
            $gs(['nulPropDiv'], ['ls_cols', 'ls_btns']);
        });
        selectOn('pidField', function (o) {
            sData.pidField = o.value;
        });
        selectOn('rootPid', function (o) {
            sData.rootPid = o.value;
        });
        selectOn('sortField', function (o) {
            sData.sortField = o.value;
        });
        selectOn('sortType', function (o) {
            sData.sortType = o.value;
        });
        selectOn('pathField', function (o) {
            sData.pathField = o.value;
        });

        $g('lsDesignReset').click(function () {
            layui.layer.confirm('此操作将撤销您对本页面所做的所有更改，确定要这样做吗？', function (index) {
                layui.layer.close(index);
                reset();
                layui.layer.msg('已撤销还原!');
            });
        });

        $g('lsDesignSave').click(function () {
            jdiyAdmin.confirm('确定要保存列表配置信息吗？保存后将不可撤消。', save);
        });

        $g('headTips').keyup(function () {
            if (this.value !== '') {
                $g('headTipsBlock').html(this.value).show();
            } else {
                $g('headTipsBlock').html('').hide();
            }
            sData.headTips = $g('headTipsBlock').html();
        });
        $g('footTips').keyup(function () {
            if (this.value !== '') {
                $g('footTipsBlock').html(this.value).show();
            } else {
                $g('footTipsBlock').html('').hide();
            }
            sData.footTips = $g('footTipsBlock').html();
        });
        $('.pageTips').click(function () {
            canvas.find('.jdiy-selected').removeClass('jdiy-selected');
            layui.element.tabChange('rtTab_' + args.uid, 'rtTab2_' + args.uid);
        });

        $(rtForm).find('.jdiy-form-help').click(function () {
            let ui = 'tree', help = $(this).data('help'),
                helpMe = (h) => typeof h == 'object' ? layer.open(h) : layer.tips(h, '.jdev-prop-' + help + args.uid, {
                    tips: [4, '#FF5722'],
                    time: 10000
                });
            help && layui.jdhp && layui.jdhp[ui] && layui.jdhp[ui][help] &&
            helpMe(
                typeof layui.jdhp[ui][help] == 'function'
                    ? layui.jdhp[ui][help](args.uid)
                    : layui.jdhp[ui][help]
            );
        });

        reset();
    }

    exports('treeDesign', {
        render: design_tr_main
    });
});